// 缓存第三个卡片对应内容
let node_dict = {}

// 异步加载成功后组合显示的名字属性
function addTitleOnAsyncSuccess(event, treeId, treeNode, msg) {
    if (!treeNode) {
        let node = zTreeObj.getNodeByParam("key", "root")
        node.title = node.name
        zTreeObj.updateNode(node)
    } else {
        let children = treeNode.children
        for (let i = 0; i < children.length; i++) {
            if (children[i].isParent) {
                children[i].title = `${children[i].name}[child: ${children[i].childrenNum}]`
            } else {
                children[i].title = `${children[i].name}[inner: ${children[i].innerNum}]`
            }
            zTreeObj.updateNode(children[i]);
        }
    }
}

// 异步加载数据处理
// 节点数据格式参见后端程序中注释说明
function ajax_data_filter_handler(treeId, parentNode, responseData) {
    let node = [];
    // responseData["data"]["menu"]["order"]是一个列表文件， 记录了数据的顺序
    for (let i = 0; i < responseData["data"]["menu"]["order"].length; i++) {
        // 根据数据顺序整理数据
        key = responseData["data"]["menu"]["order"][i]
        node.push(responseData["data"]["menu"][key])
    }
    // 返回数据
    return node
}

// 展开前将同级的其他节点收起
function beforeExpand(treeId, treeNode) {
    // 获取上级节点
    let nodeParent = treeNode.getParentNode()
    let nodeChildren;
    // 如果存在上级节点
    if (nodeParent) {
        // 获取子节点
        nodeChildren = nodeParent.children
        // 循环子节点把所有节点都收起来。注意: 当前节点也被收起来了。
        for (let i = 0; i < nodeChildren.length; i++) {
            zTreeObj.expandNode(nodeChildren[i], false);
        }
    }
    // 返回真，当前节点会被打开
    return true
}

// 菜单添加处理，异步POST提交新增信息到后端
function handlerToAddMenu(event) {
    treeNode = event.data.treeNode
    let id_parent = $('#MenuModal #id_parent')
    // 如果没有父节点并且本身是父节点，说明是虚拟根节点
    if (!treeNode.getParentNode() && treeNode.isParent) {
        id_parent.val(0);
    } else {
        // 非虚拟根节点，当前节点作为父节点，把key传到后端处理
        id_parent.val(event.data.treeNode.key);
    }
    $.ajax({
        url: menu_add_url,
        type: "POST",
        data: $('#MenuModal form').serialize(),
        success: function (data) {
            // 模态框显示页面
            $('#MenuModal .modal-body').html(data);
            // 如果没有error字段，说明没有错误，返回完全正确
            // 确定按钮的功能取消，同时刷新当前节点
            // 如果有问题，不处理确定按钮，还是可以继续提交
            if (data.indexOf("error") === -1) {
                // 取消按钮功能
                $('#MenuModal .modal_btn').unbind().addClass('d-none');
                // 父节点因为子目录加一，所以及时修改显示名称
                // 注意: 虚拟根节点不需要此操作
                if (treeNode.key !== "root") {
                    treeNode.childrenNum += 1
                    treeNode.title = `${treeNode.name}[child: ${treeNode.childrenNum}]`
                    zTreeObj.updateNode(treeNode)
                    // TODO 可以只在页面上显示，不去向后端请求，考虑情况太多，并且不是主要矛盾，先搁置，后期优化
                }
                // 更新子节点信息
                zTreeObj.reAsyncChildNodes(treeNode, 'refresh');
                // 6s后主动关闭模态框
                setTimeout(function () {
                    $('#MenuModal').modal("hide");
                }, 6000);
            }
        },
        error: function (data) {
            console.log(data);
        }
    });
}

// 显示删除菜单节点表单的模态框并处理删除操作
function handlerToDeteleteMenu(treeId, treeNode) {
    if (treeNode.childrenNum > 0 || treeNode.innerNum > 0) {
        swal({
            title: "无法删除！",
            text: "此节点下有子节点或按钮链接，请确保此节点下相关链接再进行删除！",
            icon: "error",
            button: " 确 定 ",
        });
        return false;
    }
    swal({
        title: "Are you sure?",
        text: "Once deleted, you will not be able to recover this node!",
        icon: "warning",
        buttons: true,
        dangerMode: true,
    }).then((willDelete) => {
        if (willDelete) {
            let url = menu_del_url_base.replace('0', treeNode.key);
            $.ajax({
                url: url,
                type: "POST",
                // 页面form只含有csrf的token数据以及json字段标志
                // delete删除函数不需要其他参数即可
                data: $('.ibox-content form').serialize(),
                dataType: 'json',
                success: function (data) {
                    parent_node = treeNode.getParentNode();
                    if (data['status'] === 0) {
                        swal({
                            title: "删除成功！",
                            text: "此节点已经成功删除",
                            icon: "success",
                            button: " 确 定 ",
                        });
                        let parentNode = treeNode.getParentNode()
                        if (parentNode.key !== "root") {
                            parentNode.childrenNum -= 1
                            parentNode.title = `${parentNode.name}[child: ${parentNode.childrenNum}]`
                            zTreeObj.updateNode(parentNode)
                        }
                        zTreeObj.removeNode(treeNode)
                    } else {
                        swal({
                            title: "删除失败！",
                            text: "此节点删除失败，失败原因是: " + data['msg'],
                            icon: "warning",
                            button: " 确 定 ",
                        });
                    }
                },
                error: function (data) {
                    console.log(data);
                }
            });
        }
    });
    return false;
}

// 菜单编辑处理，异步POST提交编辑信息到后端
function handlerToEditMenu(event) {
    // 当前节点，上游传入
    let treeNode = event.data.treeNode
    // 当前节点的父节点，确定所属父节点使用
    let parentNode = treeNode.getParentNode()
    // 传递表单中填写的名称，如果有修改需要更新显示
    let title = $('#MenuModal #id_title').val();
    // 格式化url
    let url = menu_edit_url_base.replace('0', treeNode.key);
    $.ajax({
        url: url,
        type: "POST",
        data: $('#MenuModal form').serialize(),
        success: function (data) {
            // 返回结果填充
            $('#MenuModal .modal-body').html(data);
            // 如果没有报错
            if (data.indexOf("error") === -1) {
                // 隐藏确定按钮
                $('#MenuModal .modal_btn').unbind().addClass('d-none');
                // 获得字段尾部，例如 ROOT[child:100] 会获得 child:100] / LEAF[inner:100] 会获得 inner:100]
                let title_tail = treeNode.title.split("[")[1]
                // 构建新的显示名称，目前没有判断，只要有修改不论是否修改title都进行重建
                // 注意：上一步获得的title_tail中括号会少一半，本次构建时要加上
                treeNode.title = `${title}[${title_tail}`
                // 更新当前节点显示
                zTreeObj.updateNode(treeNode);
                // 6s后主动关闭模态框
                setTimeout(function () {
                    $('#MenuModal').modal("hide");
                }, 6000);
            }
        },
        error: function (data) {
            console.log(data);
        }
    });
}

// 鼠标移开隐藏添加按钮
// 如果没有这个函数，添加按钮就会一直在页面上显示
function hiddenAddHoverBtn(treeId, treeNode) {
    $("#addBtn_" + treeNode.tId).unbind().remove();
}

// 显示添加按钮并绑定添加处理函数，默认没有添加按钮
function showAddHoverBtn(treeId, treeNode) {
    // 不是父节点不用显示添加按钮
    if (!treeNode.isParent) {
        return false;
    }
    // 如果节点处于编辑状态或者检测已经有按钮了，则直接进行退出
    if (treeNode.editNameFlag || $(`#addBtn_${treeNode.tId}`).length > 0) {
        return;
    }
    // 定位添加按钮的位置
    let sObj = $(`#${treeNode.tId}_span`);
    // 添加按钮的html字符串
    let addStr = `<span class='button add' id='addBtn_${treeNode.tId}' title='add node' onfocus='this.blur();'></span>`;
    sObj.after(addStr);
    // 给按钮绑定点击方法
    let btn = $(`#addBtn_${treeNode.tId}`);
    if (btn) {
        // 显示添加节点表单的模态框
        btn.bind("click", {"treeNode": treeNode}, showModalToAddNodeHandler);
    }
}

// 显示添加菜单节点表单的模态框
function showModalToAddNodeHandler(event) {
    event.stopPropagation();
    $.ajax({
        url: menu_add_url,
        success: function (data) {
            let treeNode = event.data.treeNode
            $('#MenuModal .modal-body').html(data);
            $('#MenuModal .modal-title').text("添加菜单");
            $('#MenuModal .modal-header small').text("菜单名称不可重复，菜单图标可以为空");
            // 绑定按钮功能
            $('#MenuModal .modal_btn').unbind().bind('click', {"treeNode": treeNode}, handlerToAddMenu).removeClass('d-none');
            $('#MenuModal').modal('show');
        },
        error: function (data) {
            console.log(data);
        }
    });
}

// 显示编辑菜单节点表单的模态框
function showModalToEditNodeHandler(treeId, treeNode) {
    let url = menu_edit_url_base.replace('0', treeNode.key);
    $.ajax({
        url: url,
        success: function (data) {
            $('#MenuModal .modal-body').html(data);
            $('#MenuModal .modal-title').text("更新菜单");
            $('#MenuModal .modal-header small').text("菜单名称不可重复，菜单图标可以为空");
            $('#MenuModal .modal_btn').unbind().bind('click', {"treeNode": treeNode}, handlerToEditMenu).removeClass('d-none');
            $('#MenuModal').modal('show');
        },
        error: function (data) {
            console.log(data);
        }
    });
    return false;
}

// 展示第二个菜单卡片、视情况展开隐藏第三张卡片
function showPermissionPanel(event, treeId, treeNode) {
    // 如果判断是虚拟根目录则只展开节点不进行任何处理
    // 展开节点操作在if后面
    if (treeNode.key !== "root") {
        // 填充第二个页面内容
        $('#menu_detail_name').text(treeNode.name);
        $('#menu_detail_icon').html(`<i class="fa ${treeNode.show_icon}"></i>`);
        $('#menu_detail_permission').text(treeNode.permission);
        $('#menu_detail_code').text(treeNode.permission_name);
        // 展示第二个页面
        $('#menu_detail').removeClass('d-none');

        // 如果有按钮链接权限则打开第三个卡片
        if (treeNode.innerNum > 0) {
            let menu_rel = $('#menu_rel');
            // 填充卡片、显示卡片，如果没有对应关系则先请求数据
            if (!node_dict.hasOwnProperty(treeNode.key)) {
                $.ajax({
                    url: menu_info_url,
                    type: 'get',
                    async: false,
                    data: {'key': treeNode.key, 'load': 1},
                    success(result) {
                        if (result["status"] === 0) {
                            node_dict[treeNode.key] = result["data"]["menu"];
                        } else {
                            swal({
                                title: "权限信息请求失败！",
                                text: "inner权限信息请求失败！",
                                icon: "error",
                                button: " 确 定 ",
                            });
                            node_dict[treeNode.key] = {};
                        }
                    },
                    error(data) {
                        console.log(data);
                    }
                });
            }
            let result = node_dict[treeNode.key]
            tbody = $('#menu_rel table tbody');
            tbody.empty();
            $.each(result, function (index, value) {
                section = `<tr><td rowspan="2"><a>${value['title']}</a></td><td>${value['permission_name']}</td></tr><tr><td style="border-top: none">${value['permission']}</td></tr>`;
                tbody.append(section);
            });
            $('#menu_rel').removeClass('d-none');
        }
        // 没有按钮链接权限，隐藏第三个卡片
        else {
            $('#menu_rel table tbody').empty();
            $('#menu_rel').addClass('d-none');
        }
    }
    // 展开节点，实现点击就展开节点的效果
    zTreeObj.expandNode(treeNode, null, null, null, true);
}

// 重命名按钮显示方法，默认全部节点显示重命名
// 根节点不显示重命名按钮
function showRenameBtn(treeId, treeNode) {
    return !(treeNode.key === "root");
}

// 删除按钮显示方法，默认全部节点显示删除
// 根节点以及有子节点的父节点不显示删除按钮
function showRemoveBtn(treeId, treeNode) {
    return (!(treeNode.key === "root") && !treeNode.hasChildren);
}

let permission_add = $('#permission_add')
let permission_edit = $('#permission_edit')
let permission_delete = $('#permission_delete')

let setting = {
    async: {
        // 启用异步加载
        enable: true,
        // 异步请求url
        url: menu_info_url,
        type: "get",
        // 自动发送对应参数给url
        autoParam: ["key"],
        // 提交静态参数
        otherParam: {"load": 0},
        // 请求后的数据进行处理
        dataFilter: ajax_data_filter_handler
    },
    edit: {
        enable: true,
        // 删除以及重命名在什么情况下起作用，函数返回true即可显示
        showRemoveBtn: showRemoveBtn,
        showRenameBtn: showRenameBtn,
    },
    view: {
        fontCss: {'color': 'black', 'font-weight': 'bold'},//字体样式函数
        // 自定义添加按钮，默认不显示
        addHoverDom: showAddHoverBtn,
        // 鼠标移出后默认不消失添加按钮，定义去除函数，隐藏添加按钮
        removeHoverDom: hiddenAddHoverBtn,
    },
    data: {
        keep: {
            // 即使没有子节点，直到属性isParent为真，则保持父节点状态
            // 修改为子节点需要通过修改节点isParent为假
            parent: true
        },
        key: {
            // 将节点属性title作为显示名称
            name: "title"
        },
    },
    callback: {
        onClick: showPermissionPanel,
        beforeExpand: beforeExpand,
        onAsyncSuccess: addTitleOnAsyncSuccess,
        beforeEditName: showModalToEditNodeHandler,
        beforeRemove: handlerToDeteleteMenu,
        // 节点禁止拖拽
        beforeDrag:function(){return false;}
    }
};

zTreeObj = $.fn.zTree.init($("#MenuTree"), setting);

// 权限添加处理
function add_permission(event) {
    let url = event.data.url;
    let form = $('#MenuModal form');
    let currentnode = zTreeObj.getSelectedNodes()[0];
    let parent_node = currentnode.getParentNode();
    $.ajax({
        url: url,
        type: "POST",
        data: form.serialize(),
        success: function (data) {
            $('#MenuModal .modal-body').html(data);
            // 如果没有error字段，说明没有错误，返回完全正确
            if (data.indexOf("error") === -1) {
                // 取消按钮功能
                $('#MenuModal .modal_btn').unbind().addClass('d-none');
                // TODO 可以只在页面上显示，不去向后端请求，考虑情况太多，并且不是主要矛盾，先搁置，后期优化
                // 更新子节点信息
                zTreeObj.reAsyncChildNodes(parent_node, 'refresh');
                // 节点设置选择状态有问题，模态框按取消之后节点会取消选择状态
                // TODO 这里使用消失二、三级菜单的方式让用户重新点击，体验不好，之后再修改
                // zTreeObj.selectNode(currentnode);
                $('#menu_detail').addClass('d-none');
                $('#menu_rel').addClass('d-none');
                // 6s后主动关闭模态框
                setTimeout(function () {
                    $('#MenuModal').modal("hide");
                }, 6000);
            }
        },
        error: function (data) {
            console.log(data);
        }
    });
}

// 权限修改处理
function edit_permission(event) {
    let url = event.data.url;
    let currentnode = zTreeObj.getSelectedNodes()[0];
    let parent_node = currentnode.getParentNode();
    $.ajax({
        url: url,
        type: "POST",
        data: $('#MenuModal form').serialize(),
        success: function (data) {
            $('#MenuModal .modal-body').html(data);
            // 如果没有error字段，说明没有错误，返回完全正确
            if (data.indexOf("error") === -1) {
                // 取消按钮功能
                $('#MenuModal .modal_btn').unbind().addClass('d-none');
                // TODO 可以只在页面上显示，不去向后端请求，考虑情况太多，并且不是主要矛盾，先搁置，后期优化
                // 更新子节点信息
                zTreeObj.reAsyncChildNodes(parent_node, 'refresh');
                // 节点设置选择状态有问题，模态框按取消之后节点会取消选择状态
                // TODO 这里使用消失二、三级菜单的方式让用户重新点击，体验不好，之后再修改
                // zTreeObj.selectNode(currentnode);
                $('#menu_detail').addClass('d-none');
                $('#menu_rel').addClass('d-none');
                // 6s后主动关闭模态框
                setTimeout(function () {
                    $('#MenuModal').modal("hide");
                }, 6000);
            }
        },
        error: function (data) {
            console.log(data);
        }
    });
}

// 显示添加权限模态框
permission_add.click(function (event) {
    event.stopPropagation();
    // 选中的节点
    let selectednode = zTreeObj.getSelectedNodes()[0];
    if (!selectednode) {
        swal({
            title: "无法添加权限！",
            text: "没有选择菜单，请选择后再继续相关操作！",
            icon: "error",
            button: " 确 定 ",
        });
        return false;
    }
    // 选择节点有子节点或者不是一个父节点(即已经有权限了)
    if (selectednode.childrenNum > 0 || !selectednode.isParent) {
        swal({
            title: "无法添加权限！",
            text: "此节点下有子节点，请确保此节点下没有子节点再进行添加权限！",
            icon: "error",
            button: " 确 定 ",
        });
        return false;
    }
    let url = permission_add.attr('href');
    $.ajax({
        url: url,
        success: function (data) {
            $('#MenuModal .modal-body').html(data);
            $('#MenuModal .modal-title').text("添加权限");
            $('#MenuModal .modal-header small').text("");
            if (data.indexOf("form") !== -1) {
                $('#MenuModal .modal_btn').unbind().bind('click', {"url": url}, add_permission).removeClass('d-none');
                $('#MenuModal #id_title').val(selectednode.name);
                $('#MenuModal #id_rel').val(selectednode.key);
            } else {
                $('#MenuModal .modal_btn').unbind().addClass('d-none');
            }
            $('#MenuModal').modal('show');
        },
        error: function (data) {
            console.log(data);
        }
    });
    return false;
});

// 显示修改权限模态框
permission_edit.click(function (event) {
    event.stopPropagation();
    // 选择的节点
    let selectednode = zTreeObj.getSelectedNodes()[0];
    if (!selectednode) {
        swal({
            title: "无法添加权限！",
            text: "没有选择菜单，请选择后再继续相关操作！",
            icon: "error",
            button: " 确 定 ",
        });
        return false;
    }
    // 如果没有权限则提示无法修改
    if (!selectednode.permission) {
        swal({
            title: "无法修改权限！",
            text: "此节点无权限，请确认后再重试！",
            icon: "error",
            button: " 确 定 ",
        });
        return false;
    }
    // 权限修改的地址
    let url = permission_edit.attr('href').replace('0', selectednode.key);
    $.ajax({
        url: url,
        success: function (data) {
            // 显示修改的模态框
            $('#MenuModal .modal-body').html(data);
            $('#MenuModal .modal-title').text("修改权限");
            $('#MenuModal .modal-header small').text("");
            if (data.indexOf("form") !== -1) {
                $('#MenuModal .modal_btn').unbind().bind('click', {'url': url}, edit_permission).removeClass('d-none');
            } else {
                $('#MenuModal .modal_btn').unbind().addClass('d-none');
            }
            $('#MenuModal').modal('show');
        },
        error: function (data) {
            console.log(data);
        }
    });
    return false;
});

// 删除权限
permission_delete.click(function (event) {
    event.stopPropagation();
    // 选择的节点
    let selectednode = zTreeObj.getSelectedNodes()[0];
    if (!selectednode) {
        swal({
            title: "无法添加权限！",
            text: "没有选择菜单，请选择后再继续相关操作！",
            icon: "error",
            button: " 确 定 ",
        });
        return false;
    }
    // 如果没有权限则提示无法修改
    if (!selectednode.permission) {
        swal({
            title: "无法修改权限！",
            text: "此节点无权限，请确认后再重试！",
            icon: "error",
            button: " 确 定 ",
        });
        return false;
    }
    // 权限修改的地址
    let url = permission_delete.attr('href').replace('0', selectednode.key);
    swal({
        title: "Are you sure?",
        text: "Once deleted, you will not be able to recover this permission!",
        icon: "warning",
        buttons: true,
        dangerMode: true,
    }).then((willDelete) => {
        if (willDelete) {
            let currentnode = zTreeObj.getSelectedNodes()[0];
            $.ajax({
                url: url,
                type: "POST",
                // 页面form只含有csrf的token数据以及json字段标志
                // delete删除函数不需要其他参数即可
                data: $('.ibox-content form').serialize(),
                dataType: 'json',
                success: function (data) {
                    if (data['status'] === 0) {
                        swal({
                            title: "删除成功！",
                            text: "权限已经成功删除",
                            icon: "success",
                            button: " 确 定 ",
                        });
                        currentnode.permission = null;
                        currentnode.permission_name = null;
                        // 节点设置选择状态有问题，模态框按取消之后节点会取消选择状态
                        // TODO 这里使用消失二、三级菜单的方式让用户重新点击，体验不好，之后再修改
                        $('#menu_detail').addClass('d-none');
                        $('#menu_rel').addClass('d-none');
                    } else {
                        swal({
                            title: "删除失败！",
                            text: "权限删除失败，失败原因是: " + data['msg'],
                            icon: "warning",
                            button: " 确 定 ",
                        });
                    }
                },
                error: function (data) {
                    console.log(data);
                }
            });
        }
    });
    return false;
});

